package cn.com.cfae.iras.doc.analyze.components.consistency;

import cn.com.cfae.iras.doc.analyze.components.BaseComponent;
import cn.com.cfae.iras.doc.analyze.components.beans.ComponentResult;
import cn.com.cfae.iras.doc.analyze.parse.TableUtil;
import cn.com.cfae.iras.doc.analyze.parse.kv.TextLayout;
import cn.com.cfae.iras.doc.analyze.parse.model.CatalogModel;
import cn.com.cfae.iras.doc.analyze.parse.model.ChapterModel;
import cn.com.cfae.iras.doc.analyze.parse.model.DocumentModel;
import cn.com.cfae.iras.doc.analyze.parse.model.TableType;
import cn.com.cfae.iras.doc.analyze.parse.model.table.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * Created by zouxun on 2018/10/29
 */
@Component("U1006")
@Scope("prototype")
public class U1006 extends BaseComponent {
    private static Logger logger = LoggerFactory.getLogger(U1006.class);

    @Autowired
    U1004 u1004;

    /**
     * @desc 检查目录中标明的各章、节的标题及相应的页码是否与正文一一对应。
     * 1、一级目录不允许顺序颠倒，完全按照表格体系要求，检查是否满足表格体系最小要求；
     * 2、二级目录允许顺序颠倒，允许二级目录合并；
     * 3、页码不允许非阿拉伯数字以外其他形式表示
     * 4、存在目录结构不一致进行提示；
     * @return
     */
    @Override
    public List<ComponentResult> handlerM() {
        logger.info("开始调用U1006组件，处理M表...............");
        String catalogId="M-0";
        String tableType="M";
        List<ComponentResult> componentResults = ruleCheck(catalogId,tableType);
        return componentResults;
    }

    @Override
    public List<ComponentResult> handlerBM() {
        logger.info("开始调用U1006组件，处理BM表...............");
        String catalogId="BM-0";
        String tableType="BM";
        List<ComponentResult> componentResults = ruleCheck(catalogId,tableType);
        return componentResults;
    }

    @Override
    public List<ComponentResult> handlerDM() {
        logger.info("开始调用U1006组件，处理DM表...............");
        String catalogId="DM-0";
        String tableType="DM";
        List<ComponentResult> componentResults = ruleCheck(catalogId,tableType);
        return componentResults;
    }

    @Override
    public List<ComponentResult> handlerBDM() {
        logger.info("开始调用U1006组件，处理BDM表...............");
        String catalogId="BDM-0";
        String tableType="BDM";
        List<ComponentResult> componentResults = ruleCheck(catalogId,tableType);
        return componentResults;
    }

    private String dealSpecialCharacter(String text){
        return text.replaceAll("[.|。|(|)|（|）|\\d|\\s]{1,}","");
    }


    private List<ComponentResult> ruleCheck(String catalogId,String tableType){
        List<ComponentResult> componentResults = new ArrayList<>();

        DocumentModel documentModel = super.getExtractData();

        try{
            //获取当前文档目录结构
            List<CatalogModel> catalogModelList = documentModel.getChapterModel(catalogId).getCatalogModels();

            //获取与表格体系匹配的正文各章节的标题
            List<ChapterModel> chapterModelList = documentModel.getChapterModels();

            //获取正文实际的章节标题
            List<ChapterModel> actualChapterModelList = documentModel.getActualChapterModelList();

            //待确认
            Boolean satisfyExistFlag = false;

            Boolean confirmExistFlag = false;

            //是否满足表格体系
            Boolean satisfyFlag = false;
            //目录与正文标题比对
            Boolean confirmFlag = false;

            //检查一级目录是否满足表格体系最小要求
            if(CollectionUtils.isNotEmpty(chapterModelList)){
                //与表格体系作对比时使用
                LinkedList<String> chapterIdList = new LinkedList<>();

                LinkedHashMap<String,ChapterModel> chapterIdMap = new LinkedHashMap<>();


                for(ChapterModel chapterModel:chapterModelList){
                    chapterIdList.add(chapterModel.getChapterId());

                    chapterIdMap.put(chapterModel.getChapterId(),chapterModel);
                }

                //获取表格体系
                List<TableItem> tableItemList = new ArrayList<>();
                if(tableType.equals("M")){
                    tableItemList = TableUtil.getInstance().initTable(TableType.M).getTableItemList();
                }else if(tableType.equals("BM")){
                    tableItemList = TableUtil.getInstance().initTable(TableType.BM).getTableItemList();
                }else if(tableType.equals("DM")){
                    tableItemList = TableUtil.getInstance().initTable(TableType.DM).getTableItemList();
                }else if(tableType.equals("BDM")){
                    tableItemList = TableUtil.getInstance().initTable(TableType.BDM).getTableItemList();
                }

                LinkedHashMap<String,String> tableItemMap = new LinkedHashMap<>();

                if(CollectionUtils.isNotEmpty(tableItemList)){
                    for(TableItem tableItem:tableItemList){
                        tableItemMap.put(tableItem.getItemNo(),tableItem.getItemName());

                        if(!chapterIdList.contains(tableItem.getItemNo())){
                            logger.info("{}{}缺失",tableItem.getItemNo(),tableItem.getItemName());
                            ComponentResult componentResult = u1004.getComponentResult(getCatalogId(), getChapterId(), getRuleTitle(), "检查一级目录是否满足表格体系最小要求",tableItem.getItemNo().concat(tableItem.getItemName()).concat("缺失"),true, getRegulationId(), 3, null, "02");
                            componentResults.add(componentResult);
                            satisfyFlag = true;
                            tableItemMap.remove(tableItem.getItemNo());
                        }
                    }
                }

                if(chapterIdList.size() == tableItemMap.size()){
                    LinkedList<String> tableItemLinkedList = new LinkedList<>(tableItemMap.keySet());

                    for(int i=0;i<chapterIdList.size();i++){
                        if(!chapterIdList.get(i).equals(tableItemLinkedList.get(i))){
                            ChapterModel chapterModel = chapterIdMap.get(chapterIdList.get(i));

                            logger.info("{}顺序与表格体系不符,实际应为：{}{}",chapterModel.getChapterTitle(),tableItemLinkedList.get(i),tableItemMap.get(tableItemLinkedList.get(i)));
                            ComponentResult componentResult = u1004.getComponentResult(getCatalogId(), getChapterId(), getRuleTitle(), "检查一级目录是否满足表格体系最小要求",chapterModel.getChapterTitle().concat(" 与表格体系顺序不符，实际应该为：").concat(tableItemLinkedList.get(i)).concat(tableItemMap.get(tableItemLinkedList.get(i))),true, getRegulationId(), 3, null, "02");

                            List<ComponentResult.TextPosition> textPositionList = new ArrayList<>();
                            if(chapterModel!=null){
                                componentResult.setPageNum(chapterModel.getStartPage());
                                TextLayout textLayout = chapterModel.getTextLayout();
                                if(textLayout!=null){
                                    ComponentResult.TextPosition textPosition = new ComponentResult().new TextPosition();
                                    textPosition.setX(textLayout.getLeft());
                                    textPosition.setY(textLayout.getTop());
                                    textPosition.setContent(textLayout.getText());
                                    textPositionList.add(textPosition);
                                    componentResult.setPageNum(textLayout.getPageNumber());
                                }
                            }
                            componentResult.setTextPosition(textPositionList);
                            componentResults.add(componentResult);
                            satisfyFlag = true;
                        }
                    }
                }
            }else{
                satisfyExistFlag = true;
                ComponentResult componentResult = u1004.getComponentResult(getCatalogId(), getChapterId(), getRuleTitle(), "检查一级目录是否满足表格体系最小要求","未识别正文中各章节标题，建议人工核对",true, getRegulationId(), 3, null, "03");
                componentResults.add(componentResult);
            }


            if(CollectionUtils.isNotEmpty(catalogModelList) && CollectionUtils.isNotEmpty(actualChapterModelList)){
                //与目录作对比时使用
                LinkedHashMap<String,ChapterModel> actualChapterModelMap = new LinkedHashMap<>();

                if(CollectionUtils.isNotEmpty(actualChapterModelList)){
                    for(ChapterModel chapterModel:actualChapterModelList){
                        if(StringUtils.isNotEmpty(chapterModel.getChapterTitle())){
                            String chapterTitle=dealSpecialCharacter(chapterModel.getChapterTitle());
                            if (chapterTitle.indexOf("章")!=-1) {
                                actualChapterModelMap.put(chapterTitle.substring(1,chapterTitle.indexOf("章")),chapterModel);
                            }
                        }
                    }
                }

                //与正文标题作对比时使用
                LinkedHashMap<String,CatalogModel> catalogModelMap = new LinkedHashMap<>();

                for(CatalogModel catalogModel:catalogModelList){
                    if(StringUtils.isNotEmpty(catalogModel.getCatalogName())){
                        String catalogName=dealSpecialCharacter(catalogModel.getCatalogName());
                        if(catalogName.indexOf("章")!=-1){
                            catalogModelMap.put(catalogName.substring(1,catalogName.indexOf("章")),catalogModel);
                        }
                    }
                }

                //目录
                Set<String> catalogOrderSet = catalogModelMap.keySet();

                Set<String> catalogOrderTempSet = new HashSet<>();

                //正文
                Set<String> chapterOrderSet = actualChapterModelMap.keySet();

                Set<String> chapterOrderTempSet = new HashSet<>();

                if(catalogOrderSet.size()>chapterOrderSet.size()){
                    logger.info("目录标题多于正文标题");

                    for(String catalogOrder:catalogOrderSet){
                        if(!actualChapterModelMap.containsKey(catalogOrder)){
                            logger.info("目录正文标题对比：{}缺失",catalogModelMap.get(catalogOrder).getCatalogName());
                            catalogOrderTempSet.add(catalogOrder);
                        }
                    }
                }else if(catalogOrderSet.size()<chapterOrderSet.size()){
                    logger.info("正文标题多于目录标题");

                    for(String chapterOrder:chapterOrderSet){
                        if(!catalogModelMap.containsKey(chapterOrder)){
                            logger.info("目录正文标题对比：{}缺失",actualChapterModelMap.get(chapterOrder).getChapterTitle());
                            chapterOrderTempSet.add(chapterOrder);
                        }
                    }
                }

                if(CollectionUtils.isNotEmpty(catalogOrderTempSet)){
                    for(String catalogOrder:catalogOrderTempSet){
                        CatalogModel catalogModel = catalogModelMap.get(catalogOrder);
                        if(catalogModel!=null){
                            ComponentResult componentResult = u1004.getComponentResult(getCatalogId(), getChapterId(), getRuleTitle(), "检查目录中标明的各章、节的标题及相应的页码是否与正文一一对应", "", true, getRegulationId(),3, null, "02");
                            componentResult.setPromptMessage(dealSpecialCharacter(catalogModel.getCatalogName()).concat("在正文中缺失"));

                            List<ComponentResult.TextPosition> textPositionList = new ArrayList<>();
                            if(catalogModel!=null){
                                TextLayout textLayout = catalogModel.getTextLayout();
                                if(textLayout!=null){
                                    ComponentResult.TextPosition textPosition = new ComponentResult().new TextPosition();
                                    textPosition.setX(textLayout.getLeft());
                                    textPosition.setY(textLayout.getTop());
                                    textPosition.setContent(textLayout.getText());
                                    componentResult.setPageNum(textLayout.getPageNumber());
                                    textPositionList.add(textPosition);
                                }
                            }
                            componentResult.setTextPosition(textPositionList);
                            componentResults.add(componentResult);
                        }
                    }

                    catalogOrderSet.removeAll(catalogOrderTempSet);
                    confirmFlag = true;
                }

                if(CollectionUtils.isNotEmpty(chapterOrderTempSet)){
                    for(String chapterOrder:chapterOrderTempSet){
                        ChapterModel chapterModel = actualChapterModelMap.get(chapterOrder);
                        if(chapterModel!=null){
                            ComponentResult componentResult = u1004.getComponentResult(getCatalogId(), getChapterId(), getRuleTitle(), "检查目录中标明的各章、节的标题及相应的页码是否与正文一一对应", "", true, getRegulationId(),chapterModel.getStartPage(), null, "02");
                            componentResult.setPromptMessage(dealSpecialCharacter(chapterModel.getChapterTitle()).concat("在正文中缺失"));
                            List<ComponentResult.TextPosition> textPositionList = new ArrayList<>();
                            if(chapterModel!=null){
                                TextLayout textLayout = chapterModel.getTextLayout();
                                if(textLayout!=null){
                                    ComponentResult.TextPosition textPosition = new ComponentResult().new TextPosition();
                                    textPosition.setX(textLayout.getLeft());
                                    textPosition.setY(textLayout.getTop());
                                    textPosition.setContent(textLayout.getText());
                                    componentResult.setPageNum(textLayout.getPageNumber());
                                    textPositionList.add(textPosition);
                                }
                            }
                            componentResult.setTextPosition(textPositionList);
                            componentResults.add(componentResult);
                        }
                    }
                    chapterOrderSet.removeAll(chapterOrderTempSet);
                    confirmFlag = true;
                }

                if(catalogOrderSet.size() == chapterOrderSet.size()){
                    for(String catalogOrder:catalogOrderSet){
                        StringBuilder promptMessage = new StringBuilder();

                        CatalogModel catalogModel = catalogModelMap.get(catalogOrder);
                        ChapterModel chapterModel = actualChapterModelMap.get(catalogOrder);

                        String catalogName=dealSpecialCharacter(catalogModel.getCatalogName());
                        String chapterTitle = dealSpecialCharacter(chapterModel.getChapterTitle());

                        if(!catalogName.equals(chapterTitle)){
                            promptMessage.append(catalogName.concat("与正文中的标题内容不一致，正文标题内容为：").concat(chapterTitle));
                        }

                        String bottomPageNum = String.valueOf(chapterModel.getBottomPageNum());

                        if(chapterModel.getBottomPageNum()==0){
                            bottomPageNum = String.valueOf(chapterModel.getStartPage());
                        }

                        if(!catalogModel.getCatalogIndex().equals(bottomPageNum)){
                            if(promptMessage.length()>0){
                                promptMessage.append("；且页码不一致，正文标题页码为：".concat(String.valueOf(chapterModel.getBottomPageNum())));
                            }else{
                                promptMessage.append(catalogName.concat("与正文中的标题页码不一致，正文标题页码为：").concat(String.valueOf(chapterModel.getBottomPageNum())));
                            }
                        }

                        if(promptMessage.length()>0){
                            ComponentResult componentResult = u1004.getComponentResult(getCatalogId(), getChapterId(), getRuleTitle(), "检查目录中标明的各章、节的标题及相应的页码是否与正文一一对应", promptMessage.toString(), true, getRegulationId(),3, null, "02");

                            List<ComponentResult.TextPosition> textPositionList = new ArrayList<>();

                            TextLayout textLayout = catalogModel.getTextLayout();
                            if(textLayout!=null){
                                ComponentResult.TextPosition textPosition = new ComponentResult().new TextPosition();
                                textPosition.setX(textLayout.getLeft());
                                textPosition.setY(textLayout.getTop());
                                textPosition.setContent(textLayout.getText());
                                textPositionList.add(textPosition);
                                componentResult.setPageNum(textLayout.getPageNumber());
                            }
                            componentResult.setTextPosition(textPositionList);
                            componentResults.add(componentResult);
                            confirmFlag= true;
                        }
                    }
                }

            }else{
                confirmExistFlag = true;

                ComponentResult componentResult = u1004.getComponentResult(getCatalogId(), getChapterId(), getRuleTitle(), "检查目录中标明的各章、节的标题及相应的页码是否与正文一一对应", "", true, getRegulationId(),3, null, "03");

                if(CollectionUtils.isNotEmpty(catalogModelList) && CollectionUtils.isEmpty(actualChapterModelList)){
                    componentResult.setPromptMessage("未识别正文各章节标题，建议人工核对");
                }else if(CollectionUtils.isEmpty(catalogModelList) && CollectionUtils.isNotEmpty(actualChapterModelList)){
                    componentResult.setPromptMessage("未识别目录，建议人工核对");
                }else if(CollectionUtils.isEmpty(catalogModelList) && CollectionUtils.isEmpty(actualChapterModelList)){
                    componentResult.setPromptMessage("未识别目录和正文各章节标题，建议人工核对");
                }
                componentResults.add(componentResult);
            }


            if(satisfyExistFlag && confirmExistFlag){
                for(ComponentResult componentResult:componentResults){
                    componentResult.setExist("03");
                }
            }else if(!satisfyExistFlag && confirmExistFlag){
                if(!satisfyFlag){
                    ComponentResult catalogComponentResult = u1004.getComponentResult(getCatalogId(), getChapterId(), getRuleTitle(), "检查一级目录是否满足表格体系最小要求","满足",false, getRegulationId(), 3, null, "03");
                    componentResults.add(catalogComponentResult);
                }else{
                    for(ComponentResult componentResult:componentResults){
                        componentResult.setExist("02");
                    }
                }
            }else if(satisfyExistFlag && !confirmExistFlag){
                if(!confirmFlag){
                    ComponentResult chapterComponentResult = u1004.getComponentResult(getCatalogId(), getChapterId(), getRuleTitle(), "检查目录中标明的各章、节的标题及相应的页码是否与正文一一对应","一致",false, getRegulationId(), 3, null, "03");
                    if(CollectionUtils.isNotEmpty(catalogModelList)){
                        List<ComponentResult.TextPosition> textPositionList = new ArrayList<>();
                        TextLayout textLayout = catalogModelList.get(0).getTextLayout();
                        if(textLayout!=null){
                            ComponentResult.TextPosition textPosition = new ComponentResult().new TextPosition();
                            textPosition.setX(textLayout.getLeft());
                            textPosition.setY(textLayout.getTop());
                            textPosition.setContent(textLayout.getText());
                            textPositionList.add(textPosition);
                            chapterComponentResult.setPageNum(textLayout.getPageNumber());
                        }
                        chapterComponentResult.setTextPosition(textPositionList);
                    }
                    componentResults.add(chapterComponentResult);
                }else{
                    for(ComponentResult componentResult:componentResults){
                        componentResult.setExist("02");
                    }
                }
            }else if(!satisfyExistFlag && !confirmExistFlag){
                if(!satisfyFlag && !confirmFlag){
                    ComponentResult catalogComponentResult = u1004.getComponentResult(getCatalogId(), getChapterId(), getRuleTitle(), "检查一级目录是否满足表格体系最小要求","满足",false, getRegulationId(), 3, null, "01");
                    componentResults.add(catalogComponentResult);
                    ComponentResult chapterComponentResult = u1004.getComponentResult(getCatalogId(), getChapterId(), getRuleTitle(), "检查目录中标明的各章、节的标题及相应的页码是否与正文一一对应", "一致", false, getRegulationId(),3, null, "01");
                    if(CollectionUtils.isNotEmpty(catalogModelList)){
                        List<ComponentResult.TextPosition> textPositionList = new ArrayList<>();
                        TextLayout textLayout = catalogModelList.get(0).getTextLayout();
                        if(textLayout!=null){
                            ComponentResult.TextPosition textPosition = new ComponentResult().new TextPosition();
                            textPosition.setX(textLayout.getLeft());
                            textPosition.setY(textLayout.getTop());
                            textPosition.setContent(textLayout.getText());
                            textPositionList.add(textPosition);
                            chapterComponentResult.setPageNum(textLayout.getPageNumber());
                        }
                        chapterComponentResult.setTextPosition(textPositionList);
                    }
                    componentResults.add(chapterComponentResult);
                }else if(!satisfyFlag && confirmFlag){
                    ComponentResult catalogComponentResult = u1004.getComponentResult(getCatalogId(), getChapterId(), getRuleTitle(), "检查一级目录是否满足表格体系最小要求","满足",false, getRegulationId(), 3, null, "02");
                    componentResults.add(catalogComponentResult);
                    for(ComponentResult componentResult:componentResults){
                        componentResult.setExist("02");
                    }
                }else if(satisfyFlag && !confirmFlag){
                    ComponentResult chapterComponentResult = u1004.getComponentResult(getCatalogId(), getChapterId(), getRuleTitle(), "检查目录中标明的各章、节的标题及相应的页码是否与正文一一对应", "一致", false, getRegulationId(),3, null, "02");
                    if(CollectionUtils.isNotEmpty(catalogModelList)){
                        List<ComponentResult.TextPosition> textPositionList = new ArrayList<>();
                        TextLayout textLayout = catalogModelList.get(0).getTextLayout();
                        if(textLayout!=null){
                            ComponentResult.TextPosition textPosition = new ComponentResult().new TextPosition();
                            textPosition.setX(textLayout.getLeft());
                            textPosition.setY(textLayout.getTop());
                            textPosition.setContent(textLayout.getText());
                            textPositionList.add(textPosition);
                            chapterComponentResult.setPageNum(textLayout.getPageNumber());
                        }
                        chapterComponentResult.setTextPosition(textPositionList);
                    }
                    componentResults.add(chapterComponentResult);
                    for(ComponentResult componentResult:componentResults){
                        componentResult.setExist("02");
                    }
                }else{
                    for(ComponentResult componentResult:componentResults){
                        componentResult.setAnnotationFlag(true);
                        componentResult.setExist("02");
                    }
                }
            }

        }catch (Exception e){
            logger.error(e.getMessage(),e);
        }

        return componentResults;
    }

}
